package main

import (
	"log"
	"time"

	"user-agent/controller"
	"user-agent/database"
	"user-agent/database/myredis"
	"user-agent/utils"

	"os"
	"os/signal"
	"syscall"

	"github.com/kataras/iris"
	"github.com/kataras/iris/context"
	"github.com/kataras/iris/sessions"
)

var (
	cookieNameForSessionID = "user-agent"
	session                = sessions.New(sessions.Config{
		Cookie:  cookieNameForSessionID,
		Expires: 45 * time.Minute, // <=0 means unlimited life
	})
)

func initDataBase() {
	if err := utils.InitConfig("./conf/config.production.yaml"); err != nil {
		log.Fatalln(err)
		return
	}
	if err := database.InitDriver(); err != nil {
		log.Fatalln(err)
		return
	}
	if err := myredis.InitRedis(); err != nil {
		log.Fatalln(err)
	}
	//关闭连接
	var gracefulStop = make(chan os.Signal)
	signal.Notify(gracefulStop, syscall.SIGTERM)
	signal.Notify(gracefulStop, syscall.SIGINT)
	go func() {
		<-gracefulStop
		database.GetDriver().Close()
		os.Exit(0)
	}()
}

func newApp() *iris.Application {
	config := utils.GetConfig()
	app := iris.New()
	app.Use(func(ctx context.Context) {
		//开发模式， 本地模式 自动登录
		if config.Dev {
			ses := session.Start(ctx)
			ses.Set("authenticated", true)
			ctx.Next()
			return
		}
		//非开发模式需要登录
		ctx.Next()
	})
	app.Get("/check", controller.AuthorziedCtrl.Get)

	app.Get("/", func(ctx iris.Context) {
		ses := session.Start(ctx)
		authenticated, _ := ses.GetBoolean("authenticated")
		if authenticated {
			ctx.Redirect("/public/index.html")
		} else {
			ctx.Redirect("/public/login.html")
		}
	})

	API := app.Party("/api", func(ctx context.Context) {
		path := ctx.Path()
		method := ctx.Method()
		//登录过滤
		if path == "/api/session" && method == "POST" {
			ctx.Next()
			return
		}
		//agent过滤
		if path == "/api/agent" && method == "POST" {
			ctx.Next()
			return
		}

		if path == "/api/db/sync" && method == "GET" {
			ctx.Next()
			return
		}

		if auth, _ := session.Start(ctx).GetBoolean("authenticated"); !auth {
			ctx.StatusCode(401)
		} else {
			session.ShiftExpiration(ctx)
			ctx.Next()
		}

	})
	//登录
	API.Post("/session", func(ctx context.Context) {
		username := ctx.PostValue("username")
		password := ctx.PostValue("password")
		if config.Account.Username == username && config.Account.Password == password {
			ses := session.Start(ctx)
			ses.Set("authenticated", true)
			ctx.StatusCode(200)
		} else {
			ctx.StatusCode(403)
		}
	})
	API.Post("/agent", controller.UserAgent.Post)
	API.Get("/agent", controller.UserAgent.Get)

	API.Get("/alive", controller.Alive.Get)
	API.Get("/del", controller.Alive.DelOne)

	API.Get("/alive/one", controller.Alive.GetOne)
	API.Get("/alive/one-records", controller.Alive.GetOneRecords)
	API.Get("/alive/one/statistics/:mac", controller.Alive.GetOneStatistic)

	API.Get("/db/sync", controller.DB.Sync)
	//API.
	//Server Static
	app.StaticWeb("/public", "./public")
	return app
}

func main() {
	initDataBase()
	app := newApp()
	app.Run(iris.Addr(":"+utils.GetConfig().Port), iris.WithoutVersionChecker)
}
